<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>C语言基础 - 指针进阶</title>
    <link rel="stylesheet" href="common.css">
    <style>
        /* 页面特有样式 */
        .pointer-card {
            background-color: #f5f9ff;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 25px;
            border-left: 4px solid #5D9CEC;
        }
        
        .array-box {
            background-color: #f0f7ff;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
        
        .function-box {
            background-color: #fff3e0;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
        
        .void-box {
            background-color: #e8f5e9;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
        
        .memory-diagram {
            background-color: #f8f8f8;
            padding: 15px;
            border-radius: 5px;
            font-family: monospace;
            margin: 15px 0;
        }
        
        .warning-note {
            background-color: #ffebee;
            border-left: 4px solid #f44336;
            padding: 12px;
            margin: 15px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>C语言基础入门课程</h1>
        </header>
        
        <nav>
            <a href="index.html">首页</a>
            <a href="02-intro.html">C语言简介与环境搭建</a>
            <a href="03-structure.html" class="current">C程序结构</a>
            <a href="04-datatypes.html">基本数据类型</a>
            <a href="05-variables.html">变量与常量</a>
            <a href="06-operators.html">运算符</a>
            <a href="07-io.html" class="current">输入输出</a>
            <a href="08-conditionals.html">条件语句</a>
            <a href="09-loops.html">循环结构</a>
            <a href="10-functions.html" class="current">函数基础</a>
            <a href="11-scope.html">作用域与存储类</a>
            <a href="12-recursion.html">递归函数</a>
            <a href="13-arrays.html">一维数组</a>
            <a href="14-multidim.html" class="current">多维数组</a>
            <a href="15-strings.html">字符串处理</a>
            <a href="16-pointers.html">指针基础</a>
            <a href="17-pointers_advanced.html" class="current">指针进阶</a>
            <a href="18-structs.html">结构体</a>
            <a href="19-files.html">文件操作</a>
            <a href="20-project.html">综合项目</a>
        </nav>
        
        <main>
            <h2>C语言指针进阶</h2>
            
            <section>
                <h3>指针进阶概述</h3>
                <p>深入理解指针与数组、函数的关系，以及void指针的特殊用途。</p>
            </section>
            
            <div class="pointer-card">
                <h3>1. 指针与数组</h3>
                
                <div class="array-box">
                    <h4>数组名与指针</h4>
                    <ul>
                        <li>数组名在大多数情况下会退化为指向首元素的指针</li>
                        <li>数组名不是变量，不能重新赋值</li>
                        <li><code>arr[i]</code> 等价于 <code>*(arr + i)</code></li>
                    </ul>
                    <pre><code>int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr;  // 等价于 &amp;arr[0]

printf("%d\n", *ptr);    // 10
printf("%d\n", ptr[1]);  // 20
printf("%d\n", *(ptr+2));// 30</code></pre>
                </div>
                
                <div class="memory-diagram">
                    <h4>指针与数组内存关系</h4>
                    <pre>
arr[0] arr[1] arr[2] arr[3] arr[4]
  ↓     ↓       ↓       ↓      ↓
 [10]  [20]    [30]    [40]   [50]
  ↑     ↑       ↑
ptr   ptr+1    ptr+2
                    </pre>
                </div>
                
                <div class="array-box">
                    <h4>指针数组 vs 数组指针</h4>
                    <pre><code>// 指针数组 - 元素为指针的数组
int *ptrArray[5];  

// 数组指针 - 指向数组的指针
int (*arrayPtr)[5];</code></pre>
                    <p>示例：</p>
                    <pre><code>int arr[3][4];
int (*ptr)[4] = arr;  // 指向含有4个int的数组的指针</code></pre>
                </div>
            </div>
            
            <div class="pointer-card">
                <h3>2. 指针与函数</h3>
                
                <div class="function-box">
                    <h4>指针作为函数参数</h4>
                    <pre><code>void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 5, y = 10;
    swap(&amp;x, &amp;y);
    printf("x=%d, y=%d\n", x, y);  // x=10, y=5
    return 0;
}</code></pre>
                </div>
                
                <div class="function-box">
                    <h4>返回指针的函数</h4>
                    <pre><code>// 返回动态分配的内存指针
int* createArray(int size) {
    int *arr = (int*)malloc(size * sizeof(int));
    for (int i = 0; i < size; i++) {
        arr[i] = i * 10;
    }
    return arr;
}

// 返回静态变量指针(有风险)
const char* getErrorMsg(int code) {
    static const char* msgs[] = {
        "Success",
        "Invalid input",
        "Out of memory"
    };
    return (code >= 0 &amp;&amp; code < 3) ? msgs[code] : "Unknown error";
}</code></pre>
                </div>
                
                <div class="warning-note">
                    <h4>注意事项</h4>
                    <ul>
                        <li>不要返回局部变量的指针</li>
                        <li>返回动态分配的内存要记得释放</li>
                        <li>函数指针是更高级的用法(后续介绍)</li>
                    </ul>
                </div>
                
                <div class="function-box">
                    <h4>指针与多维数组参数</h4>
                    <pre><code>// 二维数组作为参数
void printMatrix(int rows, int cols, int mat[rows][cols]) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%3d", mat[i][j]);
        }
        printf("\n");
    }
}

// 等价写法
void printMatrix2(int rows, int cols, int *mat) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%3d", *(mat + i * cols + j));
        }
        printf("\n");
    }
}</code></pre>
                </div>
            </div>
            
            <div class="pointer-card">
                <h3>3. void指针简介</h3>
                
                <div class="void-box">
                    <h4>void指针特性</h4>
                    <ul>
                        <li>可以指向任何类型的数据</li>
                        <li>不能直接解引用，必须先转换为具体类型</li>
                        <li>常用于通用函数实现</li>
                    </ul>
                    <pre><code>void *ptr;  // void指针声明</code></pre>
                </div>
                
                <div class="void-box">
                    <h4>示例：内存拷贝函数</h4>
                    <pre><code>// 自定义内存拷贝函数
void myMemcpy(void *dest, const void *src, size_t n) {
    char *d = (char *)dest;
    const char *s = (const char *)src;
    
    for (size_t i = 0; i < n; i++) {
        d[i] = s[i];
    }
}

int main() {
    int arr1[5] = {1, 2, 3, 4, 5};
    int arr2[5];
    
    myMemcpy(arr2, arr1, sizeof(arr1));
    
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr2[i]);  // 1 2 3 4 5
    }
    
    return 0;
}</code></pre>
                </div>
                
                <div class="warning-note">
                    <h4>使用注意</h4>
                    <ul>
                        <li>void指针算术运算需要先转换为具体类型</li>
                        <li>malloc/calloc返回void指针</li>
                        <li>类型转换可能带来对齐问题</li>
                    </ul>
                </div>
            </div>
            
            <section>
                <h3>综合示例：通用排序函数</h3>
                <pre><code>#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

// 通用冒泡排序函数
void bubbleSort(void *arr, size_t count, size_t size, 
                int (*compare)(const void *, const void *)) {
    for (size_t i = 0; i < count-1; i++) {
        for (size_t j = 0; j < count-i-1; j++) {
            void *a = (char *)arr + j * size;
            void *b = (char *)arr + (j+1) * size;
            
            if (compare(a, b) > 0) {
                // 交换元素
                char temp[size];
                memcpy(temp, a, size);
                memcpy(a, b, size);
                memcpy(b, temp, size);
            }
        }
    }
}

// 比较函数
int compareInt(const void *a, const void *b) {
    return *(const int *)a - *(const int *)b;
}

int compareStr(const void *a, const void *b) {
    return strcmp(*(const char **)a, *(const char **)b);
}

int main() {
    // 排序整数数组
    int nums[] = {5, 2, 8, 1, 4};
    bubbleSort(nums, 5, sizeof(int), compareInt);
    
    printf("排序后的整数: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", nums[i]);
    }
    
    // 排序字符串数组
    const char *names[] = {"张三", "李四", "王五", "赵六"};
    bubbleSort(names, 4, sizeof(char *), compareStr);
    
    printf("\n排序后的字符串: ");
    for (int i = 0; i < 4; i++) {
        printf("%s ", names[i]);
    }
    
    return 0;
}</code></pre>
            </section>
        </main>
        
        <footer>
             <p>&copy; </p>
        </footer>
        
        <!-- 二维码区域 -->

    </div> <!-- 结束.container -->
</body>
</html>